home *** CD-ROM | disk | FTP | other *** search
- /* ManageDisplayList.c */
- /*
- * Copyright © 1993-94 Apple Computer Inc. All rights reserved.
- */
- #include "DisplayNameRegistry.h"
- pascal short SortCompareProc(
- void *refCon,
- const TwistDownHdl listElementA,
- const TwistDownHdl listElementB
- );
-
- void DrawListElement(
- TwistDownPtr twistDownPtr, /* Locked data handle */
- const Rect *viewRect, /* Draw in this area */
- short vIndent
- );
- /*
- * Parameters for the print handler.
- */
- #define kPrintoutHeaderFont "\pHelvetica"
- #define kPrintoutHeaderFontSize 9
- #define kPrintoutHeaderGap 4
- #define kPrintoutHeaderStyle bold
-
- /*
- * Sort the registry list on the given criterion. Then, for all elements of the
- * registry list, if the primary sort key changes, build a new display list
- * element, otherwise extend the current display list.
- * primary (text from sort key)
- * secondary (text from other string)
- * contents
- */
- void
- SortAndDisplayBrowserWindow(
- register BrowserPtr browserPtr
- )
- {
- OSErr status;
- TwistDownHdl registryElement;
- TwistDownSiblingSet secondarySiblingSet;
- char *pathName;
- char *oldPrimary;
- char *foundProperty;
- Boolean newPrimary;
- Ptr primaryText;
- unsigned short primaryTextLength;
- UInt32 oldRegEntryID;
- UInt32 newRegEntryID;
- Ptr secondaryText;
- unsigned short secondaryTextLength;
- char oneLineWork[kOneLineFormatLength];
- #define REG_ELEM (**registryElement)
- #define SEC (secondarySiblingSet)
- #define SEC_ELEM (**SEC.thisElement)
- #define DIS_ELEM (**DIS.thisElement)
-
- SetCursor(*GetCursor(watchCursor));
- status = SortTwistDownList(
- ®.firstElement,
- SortCompareProc,
- browserPtr
- );
- if (status != noErr)
- NonFatalError(status, "\pNo memory to sort list");
- else {
- InitializeDisplayList(browserPtr);
- oldPrimary = "";
- oldRegEntryID = 0;
- for (status = noErr, registryElement = REG.firstElement;
- status == noErr && registryElement != NULL;
- registryElement = REG_ELEM.nextElement) {
- newRegEntryID = UnpackDataRecord(
- *registryElement, &pathName, &foundProperty);
- if (BROWSER.sortByName) {
- primaryText = (Ptr) pathName;
- primaryTextLength = strlen(pathName);
- secondaryText = (Ptr) foundProperty;
- secondaryTextLength = strlen(foundProperty);
- }
- else {
- primaryText = (Ptr) foundProperty;
- primaryTextLength = strlen(foundProperty);
- secondaryText = (Ptr) pathName;
- secondaryTextLength = strlen(pathName);
- }
- newPrimary = (strcmp(oldPrimary, (char *) primaryText) != 0);
- if (BROWSER.sortByName && newPrimary == FALSE)
- newPrimary = (newRegEntryID != oldRegEntryID);
- /*
- * If this is a new primary element, extend the primary display
- * list and start a new secondary list for the new primary element.
- */
- if (newPrimary) {
- oldPrimary = (char *) primaryText;
- oldRegEntryID = newRegEntryID;
- status = MakeTwistDownSibling(
- &DIS,
- kPrimaryIndentLevel,
- primaryTextLength,
- primaryText
- );
- NewTwistDownSiblingSet(&SEC);
- }
- /*
- * Store the current secondary element as a member of the current
- * secondary sibling set. If this is the first member, plug it
- * into the current primary element.
- *
- * But first, try to scrunch one-line values so the secondary
- * text and its value fit onto a single line.
- */
- if (OneLineProperty(
- (char *) secondaryText,
- REG_ELEM.subElement,
- oneLineWork
- )) {
- status = MakeTwistDownSibling( /* One-liner */
- &SEC,
- kSecondaryIndentLevel,
- strlen(oneLineWork),
- (Ptr) oneLineWork
- );
- }
- else {
- status = MakeTwistDownSibling( /* Multi-line name */
- &SEC,
- kSecondaryIndentLevel,
- secondaryTextLength,
- secondaryText
- );
- if (status == noErr) { /* Multi-line data */
- SEC_ELEM.subElement = REG_ELEM.subElement;
- if (SEC_ELEM.subElement != NULL)
- SEC_ELEM.flag |= kHasTwistDown;
- }
- }
- if (status == noErr) {
- SEC_ELEM.flag |= (REG_ELEM.flag & kUserFlagMask);
- if (DIS_ELEM.subElement == NULL) {
- DIS_ELEM.subElement = SEC.firstElement;
- DIS_ELEM.flag |= kHasTwistDown;
- }
- }
- } /* For all registry elements */
- CreateVisibleList(BROWSER.theList, DIS.firstElement);
- }
- InitCursor();
- #undef REG_ELEM
- #undef SEC
- #undef SEC_ELEM
- #undef DIS_ELEM
- }
-
- pascal short
- SortCompareProc(
- void *refCon,
- const TwistDownHdl listElementA,
- const TwistDownHdl listElementB
- )
- {
- short result;
- char *pathNameA;
- char *foundPropertyA;
- char *pathNameB;
- char *foundPropertyB;
- UInt32 regEntryA;
- UInt32 regEntryB;
- #define browserPtr ((BrowserPtr) refCon)
-
- regEntryA = UnpackDataRecord(*listElementA, &pathNameA, &foundPropertyA);
- regEntryB = UnpackDataRecord(*listElementB, &pathNameB, &foundPropertyB);
- if (BROWSER.sortByName) {
- result = strcmp(pathNameA, pathNameB);
- if (result == 0) {
- result = (regEntryA > regEntryB) ? +1
- : (regEntryA < regEntryB) ? -1
- : 0;
- }
- if (result == 0)
- result = strcmp(foundPropertyA, foundPropertyB);
- }
- else {
- result = strcmp(foundPropertyA, foundPropertyB);
- if (result == 0) {
- result = strcmp(pathNameA, pathNameB);
- if (result == 0) {
- result = (regEntryA > regEntryB) ? +1
- : (regEntryA < regEntryB) ? -1
- : 0;
- }
- }
- }
- return (result);
- #undef browserPtr
- }
-
- /*
- * Clean out the current display list. This requires some small amount of care as
- * the value (third-level) list is a direct pointer into the registry list.
- */
- void
- InitializeDisplayList(
- register BrowserPtr browserPtr
- )
- {
- TwistDownHdl primaryList;
- TwistDownHdl secondaryList;
- #define PRI (**primaryList)
- #define SEC (**secondaryList)
-
- for (primaryList = DIS.firstElement;
- primaryList != NULL;
- primaryList = PRI.nextElement) {
- for (secondaryList = PRI.subElement;
- secondaryList != NULL;
- secondaryList = SEC.nextElement) {
- SEC.subElement = NULL;
- }
- }
- DisposeTwistDownHdl(DIS.firstElement, NULL, 0);
- NewTwistDownSiblingSet(&DIS);
- #undef PRI
- #undef SEC
- }
-
-
- /*
- * This is called to display the current element.
- */
- pascal void
- DisplayListDrawProc(
- ListHandle twistDownListHdl, /* The list itself */
- TwistDownPtr twistDownPtr, /* Locked data handle */
- const Rect *viewRect /* Draw in this area */
- )
- {
- short textWidth;
- short pictWidth; /* But, there are two picts */
- Rect pictRect;
- Rect textRect;
- Boolean isLeftJustify;
- PicHandle picHandle;
- FontInfo info;
- #define ELEM (*twistDownPtr)
-
- UNUSED(twistDownListHdl);
- isLeftJustify = (GetSysDirection() == 0);
- pictWidth = CharWidth('M') * 2; /* Width of one pict */
- pictRect = *viewRect; /* Rect for one pict */
- if (isLeftJustify) /* Left-justify */
- pictRect.right = pictRect.left + pictWidth;
- else { /* Right-justify */
- pictRect.left = pictRect.right - pictWidth;
- pictWidth = (-pictWidth);
- }
- GetFontInfo(&info);
- switch (ELEM.indentLevel) {
- case kPrimaryIndentLevel:
- textRect = *viewRect;
- break;
- case kSecondaryIndentLevel:
- /*
- * If only one bit is set, tab over once.
- */
- switch (ELEM.flag & (kSavedInNVRAM | kSavedOnDisk)) {
- case 0:
- OffsetRect(&pictRect, pictWidth * 2, 0);
- break;
- case kSavedInNVRAM:
- case kSavedOnDisk:
- OffsetRect(&pictRect, pictWidth, 0);
- break;
- default:
- break;
- }
- if ((ELEM.flag & kSavedInNVRAM) != 0) {
- picHandle = GetPicture(PICT_InNVRAM);
- if (picHandle != NULL)
- DrawPicture(picHandle, &pictRect);
- OffsetRect(&pictRect, pictWidth, 0);
- }
- if ((ELEM.flag & kSavedOnDisk) != 0) {
- picHandle = GetPicture(PICT_OnDisk);
- if (picHandle != NULL)
- DrawPicture(picHandle, &pictRect);
- OffsetRect(&pictRect, pictWidth, 0);
- }
- SectRect(&pictRect, viewRect, &textRect);
- break;
- case kValueIndentLevel:
- default:
- OffsetRect(&pictRect, pictWidth, 0);
- SectRect(&pictRect, viewRect, &textRect);
- break;
- }
- if (isLeftJustify)
- MoveTo(textRect.left, textRect.top + info.ascent);
- else {
- textWidth = TextWidth(ELEM.data, 0, ELEM.dataLength);
- MoveTo(textRect.right - textWidth, textRect.top + info.ascent);
- }
- DrawText(ELEM.data, 0, ELEM.dataLength);
- #undef ELEM
- }
-
-